package com.shop.cereshop.agent.service.user.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.cereshop.agent.dao.referral.AgentReferralDAO;
import com.shop.cereshop.agent.dao.user.CereAgentPrivateDAO;
import com.shop.cereshop.agent.dao.user.CereAgentUserDAO;
import com.shop.cereshop.agent.dao.user.CereAgentUserRoleDAO;
import com.shop.cereshop.agent.page.user.CereAgentUserVO;
import com.shop.cereshop.agent.param.user.LoginDTO;
import com.shop.cereshop.agent.param.user.RegisterDTO;
import com.shop.cereshop.agent.service.agentAuth.AgentRealnameAuthService;
import com.shop.cereshop.agent.service.user.CereAgentRoleService;
import com.shop.cereshop.agent.service.user.CereAgentUserRoleService;
import com.shop.cereshop.agent.service.user.CereAgentUserService;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.agent.CereAgentRealnameAuth;
import com.shop.cereshop.commons.domain.agent.CereAgentUserRole;
import com.shop.cereshop.commons.domain.agent.CereAgentPrivate;
import com.shop.cereshop.commons.domain.agent.CereAgentRole;
import com.shop.cereshop.commons.domain.agent.CereAgentUser;
import com.shop.cereshop.commons.domain.referral.AgentReferralRelation;
import com.shop.cereshop.commons.domain.userAuth.UserRealnameAuthRespond;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EncryptUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
public class CereAgentUserServiceImpl extends ServiceImpl<CereAgentUserDAO, CereAgentUser>
    implements CereAgentUserService {

  @Autowired
  private CereAgentUserRoleDAO agentUserRoleDAO;

  @Autowired
  private CereAgentPrivateDAO cereAgentPrivateDAO;

  @Autowired
  private CereAgentUserDAO cereAgentUserDAO;

  @Autowired
  private AgentReferralDAO agentReferralDAO;

  @Autowired
  private CereAgentRoleService cereAgentRoleService;

  @Autowired
  private CereAgentUserRoleService cereAgentUserRoleService;

  @Autowired
  private AgentRealnameAuthService agentRealnameAuthService;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public CereAgentUserVO addAllUserInfo(String inviteCode, RegisterDTO registerDTO, String ip, CereAgentPrivate cereAgentPrivate) throws CoBusinessException {
    LocalDateTime now = LocalDateTime.now();
    // 1、在用户基础信息表种插入数据
    CereAgentUser cereAgentUser = CereAgentUser.builder()
            .phone(registerDTO.getPhone())
            .createTime(now)
            .updateTime(now)
            .updateTime(now)
            .registerIp(ip)
            .lastLoginType(cereAgentPrivate.getRoleType())
            .lastLoginIp(ip)
            .build();
    cereAgentUserDAO.insert(cereAgentUser);
    // 2、向私有表种插入数据
    CereAgentPrivate agentPrivate = CereAgentPrivate.builder()
            .agentUserId(cereAgentUser.getAgentUserId())
            .inviteCode(inviteCode)
            .createTime(now)
            .updateTime(now)
            .roleType(cereAgentPrivate.getRoleType())
            .ifFormal(IntegerEnum.NO.getCode())
            .build();
    cereAgentPrivateDAO.insert(agentPrivate);
    // 3、查询角色类型对应的角色id
    CereAgentRole roleInfo = cereAgentRoleService.lambdaQuery()
            .eq(CereAgentRole::getRoleType, cereAgentPrivate.getRoleType())
            .one();
    if (roleInfo != null) {
      // 4、向用户角色与关系表种插入数据
      CereAgentUserRole cereAgentUserRole = CereAgentUserRole.builder()
              .agentRoleId(roleInfo.getAgentRoleId())
              .agentUserId(cereAgentUser.getAgentUserId())
              .createTime(now)
              .build();
      agentUserRoleDAO.insert(cereAgentUserRole);
    } else {
      throw new CoBusinessException("查询不到角色: " + cereAgentPrivate.getRoleType() + " 该角色不存在");

    }
    // 5、向推广关系表中插入数据
    if (IntegerEnum.ROLE_TYPE_AGENT.getCode().equals(cereAgentPrivate.getRoleType())){
      AgentReferralRelation agentReferralRelation = AgentReferralRelation.builder()
              .refereeId(cereAgentPrivate.getAgentUserId())
              .referrerId(cereAgentUser.getAgentUserId())
              .refereeType(IntegerEnum.REFEREE_TYPE_AGENT.getCode())
              .createTime(now)
              .build();
      agentReferralDAO.insert(agentReferralRelation);
    } else if (IntegerEnum.ROLE_TYPE_SALESMAN.getCode().equals(cereAgentPrivate.getRoleType())) {
      AgentReferralRelation agentReferralRelation = AgentReferralRelation.builder()
              .refereeId(cereAgentPrivate.getAgentUserId())
              .referrerId(cereAgentUser.getAgentUserId())
              .refereeType(IntegerEnum.ROLE_TYPE_SALESMAN.getCode())
              .createTime(now)
              .build();
      agentReferralDAO.insert(agentReferralRelation);
    }
    CereAgentUserVO cereAgentUserVO = new CereAgentUserVO();
    cereAgentUserVO.setPhone(registerDTO.getPhone());
    cereAgentUserVO.setAgentUserId(cereAgentUser.getAgentUserId());
    cereAgentUserVO.setState(cereAgentUser.getState());
    cereAgentUserVO.setIfBlack(cereAgentUser.getIfBlack());
    cereAgentUserVO.setInviteCode(agentPrivate.getInviteCode());
    cereAgentUserVO.setDeleted(cereAgentUser.getDeleted());
    cereAgentUserVO.setLastLoginType(cereAgentUser.getLastLoginType());
    return cereAgentUserVO;
  }

  @Override
  public CereAgentUser selectCereAgentPrivateByPhone(String phone) {
    return cereAgentUserDAO.selectUserByPhone(phone);
  }

  @Override
  public CereAgentUserVO getRoleById(Long agentUserId, Integer roleType) {
    return cereAgentUserDAO.getRoleById(agentUserId, roleType);
  }

  @Override
  public void updateLastLoginIp(Long agentUserId, String ip) {
    CereAgentUser user = new CereAgentUser();
    user.setAgentUserId(agentUserId);
    user.setLastLoginIp(ip);
    cereAgentUserDAO.updateById(user);
  }

  @Override
  public CereAgentPrivate selectCereAgentUserByIdAndRoleType(Long agentUserId, Integer lastLoginType) {
    return cereAgentUserDAO.selectCereAgentUserByIdAndRoleType(agentUserId, lastLoginType);
  }

  @Override
  public Integer updateLoginPassword(LoginDTO param) {
    param.setPassword(EncryptUtil.encrypt(param.getPassword()));
    return cereAgentUserDAO.updateLoinPassword(param);
  }

  @Override
  public CereAgentUser selectByUserId(Long agentUserId) {
    return cereAgentUserDAO.selectById(agentUserId);
  }

  @Override
  public void updateLastLoginType(Long agentUserId, Integer roleType) {
    cereAgentUserDAO.updateLastLoginType(agentUserId, roleType);
  }

  @Override
  public CereAgentUserVO getUserInfo(Long agentUserId) {
    CereAgentUserVO cereAgentUserVO = new CereAgentUserVO();
    //todo:查询用户是否签署合同
    //查询用户是否实名
    CereAgentRealnameAuth realnameAuth = agentRealnameAuthService.lambdaQuery()
            .eq(CereAgentRealnameAuth::getAgentUserId, agentUserId)
            .one();
    if (realnameAuth != null) {
      cereAgentUserVO.setRealnameState(realnameAuth.getAuthStatus());
    } else {
      cereAgentUserVO.setRealnameState(IntegerEnum.REALNAME_AUTH_STATUS_NO.getCode());
    }
    //查询用户拥有几种角色
    Integer hasRole = cereAgentUserRoleService.hasRole(agentUserId);
    cereAgentUserVO.setHasRole(hasRole);
    return cereAgentUserVO;
  }
}
